package com.woniuxy.goods.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.generator.IFill;
import com.woniuxy.core.util.StateNum;
import com.woniuxy.goods.dto.AttrGroupDto;
import com.woniuxy.goods.dto.AttrInfoDto;
import com.woniuxy.goods.entity.AttributeGroup;
import com.woniuxy.goods.entity.AttributeInfo;
import com.woniuxy.goods.mapper.AttributeInfoMapper;
import com.woniuxy.goods.param.AddAttrInfoParam;
import com.woniuxy.goods.param.FindConfigPageParam;
import com.woniuxy.goods.param.UpdateAttrInfoParam;
import com.woniuxy.goods.service.AttributeConfigService;
import com.woniuxy.goods.service.AttributeInfoService;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * <p>
 *  服务实现类
 * </p>
 * 属性服务层实现类
 * @author ...
 * @since 2024年05月25日
 */
@Service
public class AttributeInfoServiceImpl extends ServiceImpl<AttributeInfoMapper, AttributeInfo> implements AttributeInfoService {

    /**
     * 属性组属性配置服务层接口
     */
    @Resource
    private AttributeConfigService attrConfigService;

    /**
     * 新增典当物品属性信息
     * @param param 新增属性对象
     * @return 属性信息
     * @throws Exception
     */
    @Override
    @GlobalTransactional(rollbackFor = Throwable.class)
    public AttributeInfo addAttrInfo(AddAttrInfoParam param) throws Exception {
        QueryWrapper<AttributeInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("attribute_name", param.getAttributeName());
        AttributeInfo info = getOne(wrapper);
        if (ObjectUtil.isNotEmpty(info)) throw new Exception("该属性名已存在");
        if (param.getAttributeType()== StateNum.ATTR_INFO_TYPE_ONLY){
            if (ObjectUtil.isNotEmpty(param.getChoiceList())) throw new Exception("不能为唯一属性定义选项值");
        }else {
            if (ObjectUtil.isEmpty(param.getChoiceList())) throw new Exception("必须赋值选项");
            if (param.getAttributeType()==StateNum.ATTR_INFO_TYPE_MULTIPLE_CHOICE){
                List list = JSONObject.parseObject(param.getChoiceList(), List.class);
                if (list.size()<=1) throw new Exception("至少赋值两个选项");
                for (Object o : list) {
                    if (ObjectUtil.isEmpty(o)) throw new Exception("存在空选项");
                }
            }
        }
        AttributeInfo bean = BeanUtil.toBean(param, AttributeInfo.class);
        List<AttributeInfo> infos = list();
        int size = infos.size()+1;
        String no = Integer.toString(size);
        if (no.length()<3){
            no = String.format("%03d",size);
        }
        bean.setAttributeOrder(no);
        save(bean);
        return bean;
    }

    /**
     * 删除典当物品属性信息
     * @param attributeId 属性id
     * @return
     * @throws Exception
     */
    @Override
    public void delAttrInfo(Integer attributeId) {
        removeById(attributeId);
        //删除属性组绑定里的对应记录
        attrConfigService.delConfigByAttrId(attributeId);
        return;
    }

    /**
     * 修改典当物品属性信息
     * @param param 修改属性对象
     * @return 属性信息
     * @throws Exception
     */
    @Override
    @GlobalTransactional(rollbackFor = Throwable.class)
    public AttributeInfo updateAttrInfo(UpdateAttrInfoParam param) throws Exception {
        AttributeInfo info = getById(param.getAttributeId());
        if (ObjectUtil.isEmpty(info)) throw new Exception("该属性不存在");
        if (!param.getAttributeName().equals(info.getAttributeName())){
            QueryWrapper<AttributeInfo> wrapper = new QueryWrapper<>();
            wrapper.eq("attribute_name", param.getAttributeName());
            AttributeInfo selectOne = getOne(wrapper);
            if (ObjectUtil.isNotEmpty(selectOne)) throw new Exception("该属性名已存在");
        }
        if (param.getAttributeType()== StateNum.ATTR_INFO_TYPE_ONLY){
            if (ObjectUtils.isNotEmpty(param.getChoiceList())) throw new Exception("不能为唯一属性定义选项值");
        }else {
            if (ObjectUtil.isEmpty(param.getChoiceList())) throw new Exception("必须赋值选项");
            if (param.getAttributeType()==StateNum.ATTR_INFO_TYPE_MULTIPLE_CHOICE){
                List list = JSONObject.parseObject(param.getChoiceList(), List.class);
                if (list.size()<=1) throw new Exception("至少赋值两个选项");
                for (Object o : list) {
                    if (ObjectUtil.isEmpty(o)) throw new Exception("存在空选项");
                }
            }
        }
        AttributeInfo bean = BeanUtil.toBean(param, AttributeInfo.class);
        updateById(bean);
        return bean;
    }

    /**
     * 根据id查询典当物品属性信息
     * @param attributeId 属性id
     * @return 属性信息
     * @throws Exception
     */
    @Override
    public AttrInfoDto findAttrInfoById(Integer attributeId) throws Exception {
        AttributeInfo info = getById(attributeId);
        if (ObjectUtil.isEmpty(info)) throw new Exception("该属性不存在");
        AttrInfoDto dto = BeanUtil.toBean(info, AttrInfoDto.class);
        if (info.getAttributeType()==StateNum.ATTR_INFO_TYPE_ONLY){
            dto.setAttributeTypeName("唯一");
        } else if (info.getAttributeType()==StateNum.ATTR_INFO_TYPE_SINGLE_CHOICE){
            dto.setAttributeTypeName("单选");
        } else if (info.getAttributeType()==StateNum.ATTR_INFO_TYPE_MULTIPLE_CHOICE){
            dto.setAttributeTypeName("多选");
        }
        Set set = JSONObject.parseObject(info.getChoiceList(), Set.class);
        dto.setChoices(set);
        return dto;
    }

    /**
     * 根据ids查询典当物品属性信息
     * @param attributeIds 属性id集合
     * @return 属性信息集合
     * @throws Exception
     */
    @Override
    public List<AttrInfoDto> findAttrInfosByIds(Set<Integer> attributeIds) {
        QueryWrapper<AttributeInfo> wrapper = new QueryWrapper<>();
        wrapper.in("attribute_id",attributeIds);
        List<AttributeInfo> infos = list(wrapper);
        List<AttrInfoDto> dtos = new ArrayList<>();
        for (AttributeInfo info : infos) {
            AttrInfoDto dto = BeanUtil.toBean(info, AttrInfoDto.class);
            if (info.getAttributeType()==StateNum.ATTR_INFO_TYPE_ONLY){
                dto.setAttributeTypeName("唯一");
            } else if (info.getAttributeType()==StateNum.ATTR_INFO_TYPE_SINGLE_CHOICE){
                dto.setAttributeTypeName("单选");
            } else if (info.getAttributeType()==StateNum.ATTR_INFO_TYPE_MULTIPLE_CHOICE){
                dto.setAttributeTypeName("多选");
            }
            Set set = JSONObject.parseObject(info.getChoiceList(), Set.class);
            dto.setChoices(set);
            dtos.add(dto);
        }
        return dtos;
    }

    /**
     * 分页查询属性
     * @param param 分页参数对象
     * @return 属性分页对象
     * @throws Exception
     */
    @Override
    public IPage<AttrInfoDto> findAttrPage(FindConfigPageParam param) {
        Page<AttributeInfo> page = new Page<>(param.getPageNum(), param.getPageSize());
        QueryWrapper<AttributeInfo> wrapper = new QueryWrapper<>();
        wrapper.orderByAsc("attribute_order");
        if (ObjectUtil.isNotEmpty(param.getAttributeName())){
            wrapper.like("attribute_name",param.getAttributeName());
        }
        page(page,wrapper);
        IPage<AttrInfoDto> iPage = page.convert(v -> {
            AttrInfoDto dto = new AttrInfoDto();
            BeanUtil.copyProperties(v, dto);
            return dto;
        });
        List<AttrInfoDto> newRecords = new ArrayList<>();
        for (AttrInfoDto record : iPage.getRecords()) {
            if (record.getAttributeType()==StateNum.ATTR_INFO_TYPE_ONLY){
                record.setAttributeTypeName("唯一");
            } else if (record.getAttributeType()==StateNum.ATTR_INFO_TYPE_SINGLE_CHOICE){
                record.setAttributeTypeName("单选");
            } else if (record.getAttributeType()==StateNum.ATTR_INFO_TYPE_MULTIPLE_CHOICE){
                record.setAttributeTypeName("多选");
            }
            Set set = JSONObject.parseObject(record.getChoiceList(), Set.class);
            record.setChoices(set);
            String list = "";
            if (ObjectUtil.isNotEmpty(set)){
                Iterator it = set.iterator();
                while (it.hasNext()){
                    list+=it.next().toString()+",";
                }
                if (list.endsWith(",")){list = list.substring(0, list.length() - 1);}
            }
            record.setChoiceList(list);
            newRecords.add(record);
        }
        iPage.setRecords(newRecords);
        return iPage;
    }
}
